package com.janyee.powerdroid.glide

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.os.Build
import android.renderscript.RSRuntimeException
import android.util.Log

import com.bumptech.glide.Glide
import com.bumptech.glide.load.Transformation
import com.bumptech.glide.load.engine.Resource
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapResource

import jp.wasabeef.glide.transformations.internal.FastBlur
import jp.wasabeef.glide.transformations.internal.RSBlur

/**
 * Created by kmlixh on 2017/3/15.
 * useage:
 * TripManager
 */


class ScaleBlurTransformation @JvmOverloads constructor(context: Context, private val mBitmapPool: BitmapPool = Glide.get(context).bitmapPool, private val mRadius: Int = ScaleBlurTransformation.MAX_RADIUS, private val scaleType: ScaleBlurTransformation.ScaleType = ScaleBlurTransformation.defaultScaleType) : Transformation<Bitmap> {

    private val mContext: Context

    constructor(context: Context, radius: Int) : this(context, Glide.get(context).bitmapPool, radius) {}
    constructor(context: Context, radius: Int, scaleType: ScaleType) : this(context, Glide.get(context).bitmapPool, radius, scaleType) {}

    init {
        mContext = context.applicationContext
    }

    override fun transform(resource: Resource<Bitmap>, outWidth: Int, outHeight: Int): Resource<Bitmap> {
        val source = resource.get()
        var bitmap = cropBitmap(source, outWidth, outHeight)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            try {
                bitmap = RSBlur.blur(mContext, bitmap, mRadius)
            } catch (e: RSRuntimeException) {
                bitmap = FastBlur.blur(bitmap, mRadius, true)
            }

        } else {
            bitmap = FastBlur.blur(bitmap, mRadius, true)
        }
        return BitmapResource.obtain(bitmap, mBitmapPool)
    }

    private fun cropBitmap(source: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
        val x: Int
        val y: Int
        val scaledWidth: Int
        val scaledHeight: Int
        val width = source.width
        val height = source.height
        if (outHeight * width / outWidth <= width) {
            scaledWidth = outWidth
            scaledHeight = height * outWidth / width
        } else {
            scaledHeight = outHeight
            scaledWidth = width * outHeight / height
        }
        var bitmap: Bitmap? = mBitmapPool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888)
        if (bitmap == null) {
            bitmap = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888)
        }
        val canvas = Canvas(bitmap!!)
        val paint = Paint()
        canvas.scale(scaledWidth / width.toFloat(), scaledHeight / height.toFloat(), 0f, 0f)
        paint.flags = Paint.FILTER_BITMAP_FLAG
        canvas.drawBitmap(source, 0f, 0f, paint)
        if (scaleType == ScaleType.None) {
            return bitmap
        } else {
            when (scaleType) {
                ScaleBlurTransformation.ScaleType.CenterCrop -> {
                    x = (scaledWidth - outWidth) / 2
                    y = (scaledHeight - outHeight) / 2
                }
                ScaleBlurTransformation.ScaleType.KeepTop -> {
                    x = (scaledWidth - outWidth) / 2
                    y = 0
                }
                ScaleBlurTransformation.ScaleType.KeepBottom -> {
                    x = (scaledWidth - outWidth) / 2
                    y = scaledHeight - outHeight
                }
                ScaleBlurTransformation.ScaleType.KeepLeft -> {
                    x = 0
                    y = (scaledHeight - outHeight) / 2
                }
                ScaleBlurTransformation.ScaleType.KeepRight -> {
                    x = scaledWidth - outWidth
                    y = (scaledHeight - outHeight) / 2
                }
                ScaleBlurTransformation.ScaleType.KeepTopLeft -> {
                    x = 0
                    y = 0
                }
                ScaleBlurTransformation.ScaleType.KeepTopRight -> {
                    x = scaledWidth - outWidth
                    y = 0
                }
                ScaleBlurTransformation.ScaleType.KeepBottomLeft -> {
                    x = 0
                    y = scaledHeight - outHeight
                }
                ScaleBlurTransformation.ScaleType.KeepBottomRight -> {
                    x = scaledWidth - outWidth
                    y = scaledHeight - outHeight
                }
                else -> {
                    x = (scaledWidth - outWidth) / 2
                    y = (scaledHeight - outHeight) / 2
                }
            }
            Log.e("====3", "x=" + x + ",y=" + y + "w=" + scaledWidth + ",h=" + scaledHeight + ",ow=" + outWidth + ",oh=" + outHeight)
            return Bitmap.createBitmap(bitmap, x, y, outWidth, outHeight, null, false)
        }
    }

    override fun getId(): String {
        return "ScaleBlurTransformation(radius=$mRadius)"
    }

    enum class ScaleType {
        None, CenterCrop, KeepLeft, KeepRight, KeepTop, KeepBottom, KeepTopLeft, KeepTopRight, KeepBottomLeft, KeepBottomRight
    }

    companion object {

        private val MAX_RADIUS = 25
        private val defaultScaleType = ScaleType.None
    }
}
